package com.oauth.common.server;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.gwtwidgets.server.spring.GWTSpringController;

import com.oauth.common.server.beans.OAuthConfigBean;
import com.oauth.common.server.beans.OAuthTokenBean;
import com.oauth.service.generic.OAuthService;
import com.oauth.service.generic.beans.OAuthServiceBean;
import com.oauth.service.generic.exception.OAuthServiceException;
import com.oauth.service.members.beans.Member;

public abstract class OAuthGwtController extends GWTSpringController{

	/**
	 * 
	 */
	private static final long serialVersionUID = -5239334872156168995L;
	
	protected OAuthConfigBean mOAuthConfigBean;
	
	protected String mTokenCookie;
	protected String mTokenSecretCookie;
	protected OAuthService mOAuthService;
	
	protected HttpServletResponse getHttpResponse(){
		return getThreadLocalResponse();
	}
	
	protected HttpServletRequest getHttpRequest(){
		return getThreadLocalRequest();
	}
	
	protected Long getMemberId() {
		Member member = (Member) getHttpRequest().getAttribute("member");
		return member.getMemberId();
	}
	
	protected Member getMember() {
		Member member = (Member) getHttpRequest().getAttribute("member");
		return member;
	}

	protected OAuthTokenBean getOAuthTokenFromCookie(){
		return getOAuthTokenFromCookie(mTokenCookie, mTokenSecretCookie);
	}
	
	protected OAuthTokenBean getOAuthTokenFromCookie(String pTokenCookieName,String pTokenSecretCookieName) {
		Cookie[] cookies = getHttpRequest().getCookies();
		
		OAuthTokenBean oauthTokenBean = new OAuthTokenBean();

		for(Cookie cookie:cookies){
			if(cookie.getName().equals(pTokenCookieName)){
				oauthTokenBean.setToken(cookie.getValue());
			}else if(cookie.getName().equals(pTokenSecretCookieName)){
				oauthTokenBean.setTokenSecret(cookie.getValue());
			}
		}
	
		if(oauthTokenBean.getToken() == null || oauthTokenBean.getTokenSecret() == null){
			return null;
		}else{
			return oauthTokenBean;
		}
	}

	protected void deleteTokenCookies() {
		clearTokenCookies(mTokenCookie, mTokenSecretCookie);
	}
	
	protected void clearTokenCookies(String pTokenCookieName,String pTokenSecretCookieName) {
		Cookie tokenCookie = new Cookie(pTokenCookieName,"");
		tokenCookie.setMaxAge(0);
		
		Cookie tokenSecretCookie = new Cookie(pTokenSecretCookieName,"");
		tokenSecretCookie.setMaxAge(0);
		
		getHttpResponse().addCookie(tokenCookie);
		getHttpResponse().addCookie(tokenSecretCookie);
	}

	protected void createTokenCookies(OAuthTokenBean pOAuthTokenBean){
		getHttpResponse().addCookie(new Cookie(mTokenCookie,pOAuthTokenBean.getToken()));
		getHttpResponse().addCookie(new Cookie(mTokenSecretCookie,pOAuthTokenBean.getTokenSecret()));
	}
	
	public OAuthConfigBean getOAuthConfigBean() {
		return mOAuthConfigBean;
	}

	public void setOAuthConfigBean(OAuthConfigBean pAuthConfigBean) {
		mOAuthConfigBean = pAuthConfigBean;
	}
	
	protected String getConsumerSecret() {
		return getOAuthConfigBean().getConsumerSecret();
	}
	
	protected String getConsumerKey() {
		return getOAuthConfigBean().getConsumerKey();
	}

	/**
	 * @param tokenCookie the mTokenCookie to set
	 */
	public void setTokenCookie(String tokenCookie) {
		mTokenCookie = tokenCookie;
	}

	/**
	 * @param tokenSecretCookie the mTokenSecretCookie to set
	 */
	public void setTokenSecretCookie(String tokenSecretCookie) {
		mTokenSecretCookie = tokenSecretCookie;
	}

	/**
	 * @return the oauthService
	 */
	public OAuthService getOAuthService() {
		return mOAuthService;
	}

	/**
	 * @param pOauthService the oauthService to set
	 */
	public void setOAuthService(OAuthService pOauthService) {
		mOAuthService = pOauthService;
	}
	
	protected <T extends OAuthServiceBean> OAuthServiceBean getToken() throws OAuthServiceException{
		return getOAuthService().getToken(getMemberId(),getServiceBeanClass());
	}
	
	protected void deleteToken() throws OAuthServiceException{
		getOAuthService().deleteToken(getMemberId(),getServiceBeanClass());
	}
	
	protected <T extends OAuthServiceBean> T persistToken(T pServiceBean) throws OAuthServiceException{
		return getOAuthService().persistToken(pServiceBean);
	}
	
	protected abstract <T extends OAuthServiceBean> Class<T> getServiceBeanClass();
	
	/*protected abstract OAuthAccessTokenBean getAccessTokenFromProvider();*/
		
/*	protected OAuthAccessTokenBean getAccessToken() {
		OAuthServiceBean token = null;
		try {
			token = getToken();
		} catch (Exception e1) {
			e1.printStackTrace();
		} //got token from db.
		if( token != null){
			return new OAuthAccessTokenBean(token.getAccessToken(),token.getAccessTokenSecret());
		}
		OAuthTokenBean oauthTokenBean = getOAuthTokenFromCookie();

		if(oauthTokenBean != null){
			OAuthAccessTokenBean accessToken = null;
			try {
				accessToken = getAccessTokenFromProvider();
				
				OAuthServiceBean serviceBean = (OAuthServiceBean) getClass().newInstance();
				
				serviceBean.setAccessToken(accessToken.getToken());
				serviceBean.setAccessTokenSecret(accessToken.getTokenSecret());
				serviceBean.setMemberId(getMemberId());
				persistToken(serviceBean); //persist in db for future use.
				deleteTokenCookies(); //delete request tokens from cookies.
			} catch (Exception e) {
				// Redirect to login page.
				e.printStackTrace();
				deleteTokenCookies();
				return null;
			}
			return accessToken;
		}
		return null;
	}
*/
}
